在 Astro 2.0.0 版本中,引入了 Content Collections
功能,這是一個極其強大的工具,用於管理和展示您的網站內容。本篇將帶您深入探討 Astro Content Collections,包括如何建立集合、定義集合結構、呈現內容,以及如何將它應用於您的網站。
Astro Content Collections 是在 Astro 項目中管理和組織內容的最佳方式。它幫助您整理文件,驗證前置資料(frontmatter),並為所有內容提供自動的 TypeScript 類型安全支持。
首先,我們需要建立一個內容集合來存放文章。
內容集合是存放在 src/content
專案目錄中的頂級目錄,例如 src/content/blog
和 src/content/authors
。值得注意的是,src/content
目錄僅用於存放內容集合,不應用於其他目的。
以 src/content/blog
為例,該目錄內可以包含如下內容:
src/
└── content/
│ │ ├── blog/
│ │ │ ├── first-post.md
│ │ │ ├── using-mdx.md
│ │ │ └── second-post.md
│ │ └── config.ts
為了確保內容的一致性和資料完整性,我們可以定義集合的架構。這樣,Astro
將能夠自動生成 TypeScript
類型,以支持您在查詢集合時的自動完成和類型檢查。
以下是定義 blog 的集合架構範例:
src/content/config.ts
import { defineCollection, z } from "astro:content";
const blog = defineCollection({
// 使用模式驗證前置資料 (frontmatter)
schema: z.object({
title: z.string(),
description: z.string(),
tags: z.array(z.string()).optional(),
// 字串轉換為日期對象
pubDate: z
.string()
.or(z.date())
.transform((val) => new Date(val)),
updatedDate: z
.string()
.optional()
.transform((str) => (str ? new Date(str) : undefined)),
heroImage: z.string().optional(),
}),
});
export const collections = { blog };
圖為 config.ts
與 .md
對應檔
]
建立並定義了集合後,您可以使用內建的內容 API 來查詢和呈現集合內容。
接下來,在 src/pages
建立一個 blog.astro
的頁面
---
import { getCollection } from "astro:content";
const allPosts = await getCollection("blog"); // 取得所有的文章內容
---
<ul>
{
allPosts.map((post) => (
<li>
<a href={`/posts/${post.slug}`}>{post.data.title}</a>
<time datetime={post.data.pubDate.toISOString()}>
{post.data.pubDate.toDateString()}
</time>
</li>
))
}
</ul>
如果您希望為每個集合項目生成單獨的頁面,可以使用動態路由。以下是在 Astro 中實現動態路由的範例:
src/pages/blog/[...slug].astro
---
import { getEntry } from "astro:content";
import MarkdownPostLayout from "../../layouts/MarkdownPostLayout.astro";
![https://ithelp.ithome.com.tw/upload/images/20230905/20093270jUZeDy2vKd.jpg](https://ithelp.ithome.com.tw/upload/images/20230905/20093270jUZeDy2vKd.jpg)
// 取得動態路由的參數
const { slug } = Astro.params;
// 查詢對應的集合項目
const entry = await getEntry("posts", slug);
// 呈現內容並使用特定的版面配置
const { Content } = await entry.render();
---
<MarkdownPostLayout frontmatter={entry.data}>
<Content />
</MarkdownPostLayout>
如果您的 tsconfig.json
文件尚未使用 Astro 的嚴格或最嚴格的 TypeScript 設置,可能需要更新該文件以啟用 strictNullChecks
。
{
// 如果您使用 "astro/tsconfigs/strict" 或 "astro/tsconfigs/strictest",則無需更改
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"strictNullChecks": true
}
}
如果在 Astro 項目中使用 .js 或 .mjs 文件,您可以在 tsconfig.json
中啟用 allowJs
以啟用 IntelliSense 和類型檢查:
{
// 如果您使用 "astro/tsconfigs/strict" 或 "astro/tsconfigs/strictest",則無需更改
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"strictNullChecks": true,
"allowJs": true
}
}
Astro Content Collections 功能為您提供了一個強大的工具,可更有效地組織和管理網站內容,同時提供了 TypeScript 型別安全和前置元驗證等功能。這不僅讓您更輕鬆地構建靜態網站和應用程序,還幫助保持項目的整潔和有序。